##loading the data and libraries 
library(tidyverse)
library(janitor)

neighbourhood_rating <- read_csv("../raw_data/neighbourhood_rating.csv") %>% 
  clean_names()
Rows: 38055 Columns: 13── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): FeatureCode, Measurement, Units, Neighbourhood rating, Gender, Urban Rural Classification, SIMD quintiles, Typ...
dbl  (2): DateCode, Value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
green_spaces <- read_csv("../raw_data/green_spaces.csv") %>% 
  clean_names()
Rows: 38451 Columns: 13── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): FeatureCode, Measurement, Units, Distance to Nearest Green or Blue Space, Age, Gender, Urban Rural Classificat...
dbl  (2): DateCode, Value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
community_belonging <-read_csv("../raw_data/community_belonging.csv") %>% 
  clean_names()
Rows: 43611 Columns: 13── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): FeatureCode, Measurement, Units, Community belonging, Gender, Urban Rural Classification, SIMD quintiles, Type...
dbl  (2): DateCode, Value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
neighbourhood_rating
green_spaces
community_belonging

#Great, no missing values

#checking missing values 
green_spaces %>%
  summarise(count = sum(is.na(green_spaces)))

community_belonging %>% 
  summarise(count = sum(is.na(community_belonging)))

neighbourhood_rating %>% 
  summarise(count = sum(is.na(neighbourhood_rating)))
neighbourhood_rating %>% 
  count(date_code)
neighbourhood_rating %>% 
  count(walking_distance_to_nearest_greenspace)
neighbourhood_rating %>% 
  count(type_of_tenure)
neighbourhood_rating %>% 
  count(type_of_tenure)
neighbourhood_rating %>% 
  count(measurement)
neighbourhood_rating %>% 
  count(units)
neighbourhood_rating %>% 
  count(simd_quintiles)
community %>% 
  count(measurement)
Error in count(., measurement) : object 'community' not found
#council areas codes 
council_areas <- read_csv("../raw_data/967937c4-8d67-4f39-974f-fd58c4acfda5.csv") %>% 
  clean_names()
Rows: 44 Columns: 14── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (7): CA, CAName, HSCP, HSCPName, HB, HBName, Country
dbl (7): _id, CADateEnacted, CADateArchived, HSCPDateEnacted, HSCPDateArchived, HBDateEnacted, HBDateArchived
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
council_areas<- council_areas %>% 
  select(ca, ca_name)
council_areas %>% 
  rename(feature_code = ca)
green_spaces_joined <- inner_join(
  green_spaces, council_areas, by = c("feature_code" = "ca"))
green_spaces_joined
community_belonging_joined <- inner_join(
  community_belonging, council_areas, by = c("feature_code" = "ca")) 
community_belonging_joined
neighbourhood_rating_joined <-  inner_join(
  neighbourhood_rating, council_areas, by = c("feature_code" = "ca"))
neighbourhood_rating_joined
neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace == "More than 10 minutes") %>% 
  count(value)
neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace == "Less than 10 minutes") %>% 
  count(neighbourhood_rating)
neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace == "More than 10 minutes") %>% 
  count(neighbourhood_rating)
neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace == "Less than 10 minutes") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace == "More than 10 minutes") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  filter(date_code == "2019",
    walking_distance_to_nearest_greenspace == "Less than 10 minutes") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  filter(date_code == "2019",
    walking_distance_to_nearest_greenspace == "More than 10 minutes") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  filter(date_code == "2019") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  filter(date_code == "2018") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  count(date_code)
neighbourhood_rating_joined %>% 
  filter(date_code == "2017") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
neighbourhood_rating_joined %>% 
  filter(date_code == "2016") %>% 
  count(ca_name) %>% 
  arrange(desc(n))
green_spaces_joined %>% 
  count(gender)

##Are there certain groups that have/ lack local access to green space?

green_spaces_joined
green_spaces_joined %>% 
  count(distance_to_nearest_green_or_blue_space)
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "A 5 minute walk or less") %>% 
  count(gender)
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "An 11 minute walk or more") %>% 
  count(gender)
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "Within a 6-10 minute walk") %>% 
  count(gender)
#age access
green_spaces_joined %>% 
  count(age)
#age access
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "A 5 minute walk or less",
         date_code == "2018") %>% 
  count(age)
#age access
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "An 11 minute walk or more") %>% 
  count(age)
green_spaces_joined
#simd_quintiles
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "A 5 minute walk or less", 
         date_code == "2013") %>% 
  count(simd_quintiles)
#simd_quintiles
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "An 11 minute walk or more") %>% 
  count(simd_quintiles)
green_spaces_joined
#simd_quintiles
green_spaces_joined %>% 
  filter(distance_to_nearest_green_or_blue_space == "A 5 minute walk or less", 
         date_code == "2019") %>% 
  count(simd_quintiles)

green_spaces_joined %>% 
  mutate(age = factor(age, levels = c("16-34 years", "35-64 years",
                                      "65 years and over", "All")),
         simd_quintiles = factor(simd_quintiles, levels = c("20% most deprived",
                                                            "80% least deprived",
                                                            "All")),
         distance_to_nearest_green_or_blue_space = factor(
           distance_to_nearest_green_or_blue_space, levels = c(
             "A 5 minute walk or less",
             "Within a 6-10 minute walk",
             "An 11 minute walk or more",
             "Don't Know"
           )
         )) 
#plotting simd_quintiles for every year to see if there're significant 
#differences for each year
#Filtering out Simd_quintiles == "All"
green_spaces_joined %>% 
  filter(simd_quintiles != "All") %>% 
ggplot(aes(x = distance_to_nearest_green_or_blue_space, fill = simd_quintiles))+
  geom_bar(position = "dodge")+
  facet_wrap(~date_code)

#plotting excluding outliers
green_spaces_joined %>% 
  filter(measurement == "Percent") %>% 
ggplot(aes(x = simd_quintiles, fill = distance_to_nearest_green_or_blue_space))+
  geom_bar(position = "dodge")+
  facet_wrap(~date_code)

#plotting excluding outliers for total years
green_spaces_joined %>% 
ggplot(aes(x = distance_to_nearest_green_or_blue_space, fill = simd_quintiles))+
  geom_bar(position = "dodge")

green_spaces_joined %>% 
    group_by(age, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = age, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
geom_col(position = "dodge")
`summarise()` has grouped output by 'age'. You can override using the `.groups` argument.

green_spaces_joined %>% 
    #filter(measurement == "Percent") %>% 
    group_by(ca_name, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = ca_name, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+ 
           geom_col(position = "dodge")+
  facet_wrap(~ca_name)
`summarise()` has grouped output by 'ca_name'. You can override using the `.groups` argument.

#simd quinitles and distance to green spaces
green_spaces_joined %>%
  filter(simd_quintiles != "All") %>% 
    group_by(simd_quintiles, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = simd_quintiles, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'simd_quintiles'. You can override using the `.groups` argument.

green_spaces_joined %>% 
    #filter(measurement == "Percent") %>% 
    group_by(, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = simd_quintiles, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
Error in FUN(X[[i]], ...) : object 'simd_quintiles' not found

#subsetting the All
green_spaces_joined %>% 
    #filter(measurement == "Percent") %>% 
    group_by(simd_quintiles, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(subset(green_spaces_joined, simd_quintiles %in% c("All")))+
  geom_col(aes(simd_quintiles, mean_percentage, fill = distance_to_nearest_green_or_blue_space))
`summarise()` has grouped output by 'simd_quintiles'. You can override using the `.groups` argument.
Error in `ggplot()`:
! Mapping should be created with `aes()` or `aes_()`.
Backtrace:
 1. ... %>% ...
 3. ggplot2:::ggplot.default(., subset(green_spaces_joined, simd_quintiles %in% c("All")))
green_spaces_joined %>% 
    #filter(measurement == "Percent") %>% 
    group_by(gender, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = gender, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'gender'. You can override using the `.groups` argument.

green_spaces_joined %>% 
    group_by(urban_rural_classification, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = urban_rural_classification, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'urban_rural_classification'. You can override using the `.groups` argument.

#type of tenure
green_spaces_joined %>% 
 filter(type_of_tenure != "All") %>% 
     group_by(type_of_tenure, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = type_of_tenure, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'type_of_tenure'. You can override using the `.groups` argument.

#household type
green_spaces_joined %>% 
  filter(household_type != "All") %>% 
    group_by(household_type, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = household_type, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'household_type'. You can override using the `.groups` argument.

#ethnicity
green_spaces_joined %>% 
    group_by(ethnicity, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = ethnicity, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'ethnicity'. You can override using the `.groups` argument.

#ethnicity and trying to subset "All"
green_spaces_joined %>% 
    group_by(ethnicity, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(subset(ethnicity %in% "All"), aes(x = ethnicity, y = mean_percentage, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'ethnicity'. You can override using the `.groups` argument.Error in ethnicity %in% "All" : object 'ethnicity' not found
   ggplot(subset(green_spaces_joined,
                 ethnicity %in% "All"), aes(x = ethnicity, y = value, fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")

#ethnicity
green_spaces_joined %>% 
    group_by(ethnicity, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = ethnicity(-c("All")), 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'ethnicity'. You can override using the `.groups` argument.Error in ethnicity(-c("All")) : could not find function "ethnicity"

#ethnicity
green_spaces_joined %>% 
    group_by(ethnicity(-c("All")), distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = ethnicity, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
Error in `group_by()`:
! Problem adding computed columns.
Caused by error in `mutate()`:
! Problem while computing `..1 = ethnicity(-c("All"))`.
Caused by error in `ethnicity()`:
! could not find function "ethnicity"
Backtrace:
  1. ... %>% ...
  5. dplyr:::group_by.data.frame(., ethnicity(-c("All")), distance_to_nearest_green_or_blue_space)
  6. dplyr::group_by_prepare(.data, ..., .add = .add, caller_env = caller_env())
  7. dplyr:::add_computed_columns(...)
  9. dplyr:::mutate_cols(...)
 11. mask$eval_all_mutate(quo)
#ethnicity
green_spaces_joined %>% 
  filter(ethnicity != "All") %>% 
    group_by(ethnicity, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = ethnicity, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'ethnicity'. You can override using the `.groups` argument.

#ethnicity
green_spaces_joined %>% 
 filter(ethnicity != "All") %>% 
    group_by(ethnicity, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = ethnicity, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'ethnicity'. You can override using the `.groups` argument.

green_spaces_joined
#gender and distance to green spaces
green_spaces_joined %>% 
 filter(gender != "All") %>% 
    group_by(gender, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = gender, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'gender'. You can override using the `.groups` argument.

#gender and distance to green spaces
green_spaces_joined %>% 
 filter(urban_rural_classification != "All") %>% 
    group_by(urban_rural_classification, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = urban_rural_classification, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'urban_rural_classification'. You can override using the `.groups` argument.

#working on neighbourhood rating

neighbourhood_rating_joined
community_belonging_joined
neighbourhood_rating_joined %>% 
  count(neighbourhood_rating)

#interesting data, maybe I’ll need to bin the data into good and poor, the difference is maybe more evident or perhaps I can plot the differences in two different plots.

neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace != "All") %>% 
    group_by(neighbourhood_rating, walking_distance_to_nearest_greenspace) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = neighbourhood_rating, 
             y = mean_percentage, 
             fill = walking_distance_to_nearest_greenspace))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'neighbourhood_rating'. You can override using the `.groups` argument.

neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace != "All", 
         neighbourhood_rating == "Very good") %>% 
    group_by(neighbourhood_rating, walking_distance_to_nearest_greenspace) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = neighbourhood_rating, 
             y = mean_percentage, 
             fill = walking_distance_to_nearest_greenspace))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'neighbourhood_rating'. You can override using the `.groups` argument.

neighbourhood_rating_joined %>% 
  filter(walking_distance_to_nearest_greenspace != "All", 
         neighbourhood_rating == "Very poor") %>% 
    group_by(neighbourhood_rating, walking_distance_to_nearest_greenspace) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = neighbourhood_rating, 
             y = mean_percentage, 
             fill = walking_distance_to_nearest_greenspace))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'neighbourhood_rating'. You can override using the `.groups` argument.

#binning into good and very good and poor and very poor

#urban/ rural areas and distance to green spaces
green_spaces_joined %>% 
 filter(urban_rural_classification != "All") %>% 
    group_by(urban_rural_classification, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = urban_rural_classification, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'urban_rural_classification'. You can override using the `.groups` argument.

#urban/ rural areas and distance to green spaces
green_spaces_joined %>% 
 filter(urban_rural_classification != "All", 
        measurement == "Percent") %>% 
    group_by(urban_rural_classification, distance_to_nearest_green_or_blue_space) %>% 
    summarise(mean_percentage = mean(value)) %>% 
  ggplot(aes(x = urban_rural_classification, 
             y = mean_percentage, 
             fill = distance_to_nearest_green_or_blue_space))+
  geom_col(position = "dodge")
`summarise()` has grouped output by 'urban_rural_classification'. You can override using the `.groups` argument.

#let’s do hypothesis testing on urban and rural

green_spaces_joined
green_spaces_joined %>% 
  count(measurement)

#are there differences in green spaces access between rural or urban

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCiMjbG9hZGluZyB0aGUgZGF0YSBhbmQgbGlicmFyaWVzIA0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGphbml0b3IpDQoNCm5laWdoYm91cmhvb2RfcmF0aW5nIDwtIHJlYWRfY3N2KCIuLi9yYXdfZGF0YS9uZWlnaGJvdXJob29kX3JhdGluZy5jc3YiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkNCmdyZWVuX3NwYWNlcyA8LSByZWFkX2NzdigiLi4vcmF3X2RhdGEvZ3JlZW5fc3BhY2VzLmNzdiIpICU+JSANCiAgY2xlYW5fbmFtZXMoKQ0KY29tbXVuaXR5X2JlbG9uZ2luZyA8LXJlYWRfY3N2KCIuLi9yYXdfZGF0YS9jb21tdW5pdHlfYmVsb25naW5nLmNzdiIpICU+JSANCiAgY2xlYW5fbmFtZXMoKQ0KYGBgDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nDQpncmVlbl9zcGFjZXMNCmNvbW11bml0eV9iZWxvbmdpbmcNCmBgYA0KDQoNCiNHcmVhdCwgbm8gbWlzc2luZyB2YWx1ZXMgDQpgYGB7cn0NCiNjaGVja2luZyBtaXNzaW5nIHZhbHVlcyANCmdyZWVuX3NwYWNlcyAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gc3VtKGlzLm5hKGdyZWVuX3NwYWNlcykpKQ0KDQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gc3VtKGlzLm5hKGNvbW11bml0eV9iZWxvbmdpbmcpKSkNCg0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBzdW1tYXJpc2UoY291bnQgPSBzdW0oaXMubmEobmVpZ2hib3VyaG9vZF9yYXRpbmcpKSkNCmBgYA0KDQoNCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBjb3VudChkYXRlX2NvZGUpDQpgYGANCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBjb3VudCh3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkNCmBgYA0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZyAlPiUgDQogIGNvdW50KHR5cGVfb2ZfdGVudXJlKQ0KYGBgDQoNCg0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZyAlPiUgDQogIGNvdW50KHR5cGVfb2ZfdGVudXJlKQ0KYGBgDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nICU+JSANCiAgY291bnQobWVhc3VyZW1lbnQpDQpgYGANCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBjb3VudCh1bml0cykNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nICU+JSANCiAgY291bnQoc2ltZF9xdWludGlsZXMpDQpgYGANCg0KDQoNCmBgYHtyfQ0KZ3JlZW5fc3BhY2VzICU+JSANCiAgY291bnQoZGF0ZV9jb2RlKQ0KDQpncmVlbl9zcGFjZXMgJT4lIA0KICBjb3VudChtZWFzdXJlbWVudCkNCg0KZ3JlZW5fc3BhY2VzICU+JSANCiAgY291bnQoZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKQ0KYGBgDQoNCg0KYGBge3J9DQpncmVlbl9zcGFjZXMNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlcyAlPiUgDQogIGNvdW50KGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlcyAlPiUgDQogIGNvdW50KGFnZSkNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlcyAlPiUgDQogIGNvdW50KGdlbmRlcikNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlcyAlPiUgDQogIGNvdW50KHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uKQ0KYGBgDQoNCmBgYHtyfQ0KZ3JlZW5fc3BhY2VzICU+JSANCiAgY291bnQoc2ltZF9xdWludGlsZXMpDQpgYGANCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nDQpgYGANCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgY291bnQoY29tbXVuaXR5X2JlbG9uZ2luZykNCmBgYA0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgY291bnQoZmVhdHVyZV9jb2RlKQ0KYGBgDQoNCmBgYHtyfQ0KI2NvdW5jaWwgYXJlYXMgY29kZXMgDQpjb3VuY2lsX2FyZWFzIDwtIHJlYWRfY3N2KCIuLi9yYXdfZGF0YS85Njc5MzdjNC04ZDY3LTRmMzktOTc0Zi1mZDU4YzRhY2ZkYTUuY3N2IikgJT4lIA0KICBjbGVhbl9uYW1lcygpDQoNCmBgYA0KDQpgYGB7cn0NCmNvdW5jaWxfYXJlYXM8LSBjb3VuY2lsX2FyZWFzICU+JSANCiAgc2VsZWN0KGNhLCBjYV9uYW1lKQ0KYGBgDQpgYGB7cn0NCmNvdW5jaWxfYXJlYXMgJT4lIA0KICByZW5hbWUoZmVhdHVyZV9jb2RlID0gY2EpDQpgYGANCg0KYGBge3J9DQpncmVlbl9zcGFjZXNfam9pbmVkIDwtIGlubmVyX2pvaW4oDQogIGdyZWVuX3NwYWNlcywgY291bmNpbF9hcmVhcywgYnkgPSBjKCJmZWF0dXJlX2NvZGUiID0gImNhIikpDQpncmVlbl9zcGFjZXNfam9pbmVkDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCmNvdW5jaWxfYXJlYXMNCmBgYA0KYGBge3J9DQpncmVlbl9zcGFjZXMNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlc19qb2luZWQNCmBgYA0KDQpgYGB7cn0NCmNvbW11bml0eV9iZWxvbmdpbmdfam9pbmVkIDwtIGlubmVyX2pvaW4oDQogIGNvbW11bml0eV9iZWxvbmdpbmcsIGNvdW5jaWxfYXJlYXMsIGJ5ID0gYygiZmVhdHVyZV9jb2RlIiA9ICJjYSIpKSANCmNvbW11bml0eV9iZWxvbmdpbmdfam9pbmVkDQpgYGANCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmdfam9pbmVkIDwtICBpbm5lcl9qb2luKA0KICBuZWlnaGJvdXJob29kX3JhdGluZywgY291bmNpbF9hcmVhcywgYnkgPSBjKCJmZWF0dXJlX2NvZGUiID0gImNhIikpDQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQNCmBgYA0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBjb3VudCh3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcih3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSA9PSAiTGVzcyB0aGFuIDEwIG1pbnV0ZXMiKSAlPiUgDQogIGNvdW50KHZhbHVlKQ0KYGBgDQoNCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmdfam9pbmVkICU+JSANCiAgZmlsdGVyKHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlID09ICJNb3JlIHRoYW4gMTAgbWludXRlcyIpICU+JSANCiAgY291bnQodmFsdWUpDQpgYGANCg0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgPT0gIkxlc3MgdGhhbiAxMCBtaW51dGVzIikgJT4lIA0KICBjb3VudChuZWlnaGJvdXJob29kX3JhdGluZykNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcih3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSA9PSAiTW9yZSB0aGFuIDEwIG1pbnV0ZXMiKSAlPiUgDQogIGNvdW50KG5laWdoYm91cmhvb2RfcmF0aW5nKQ0KYGBgDQoNCmBgYHtyfQ0KI2FwcGFyZW50bHkgc291dGggTGFua2Fyc2hpcmUgaXMgY2Egd2hlcmUgcGVvcGxlIGhhdmUgYm90aCBhY2Nlc3MgdG8gYSBncmVlbiBzcGFjZSBpbiBtb3JlIG9yIGxlc3MgdGhhbiAxMCBtaW5zLiBUaGlzIHByb2JhYmx5IGJlY2F1c2UgdGhlIHNhbXBsZSBnZW5lcmFsbHkgY29udGFpbnRzIG1vcmUgdmFsdWVzIGZvciBTb3V0aCBMYW5rYXJzaGlyZS4gUGVyaGFwcyBJIGNhbiBkbyBhIHByb3BvcnRpb24/ICANCiNQZXIgY2FwaXRhID0gVW5pdCAvIE51bWJlciBvZiBwZW9wbGUgaW4gYSBwb3B1bGF0aW9uDQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgPT0gIkxlc3MgdGhhbiAxMCBtaW51dGVzIikgJT4lIA0KICBjb3VudChjYV9uYW1lKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCmBgYA0KDQpgYGB7cn0NCiNhcHBhcmVudGx5IHNvdXRoIExhbmthcnNoaXJlIGlzIGNhIHdoZXJlIHBlb3BsZSBoYXZlIGJvdGggYWNjZXNzIHRvIGEgZ3JlZW4gc3BhY2UgaW4gbW9yZSBvciBsZXNzIHRoYW4gMTAgbWlucy4gVGhpcyBwcm9iYWJseSBiZWNhdXNlIHRoZSBzYW1wbGUgZ2VuZXJhbGx5IGNvbnRhaW50cyBtb3JlIHZhbHVlcyBmb3IgU291dGggTGFua2Fyc2hpcmUuIFBlcmhhcHMgSSBjYW4gZG8gYSBwcm9wb3J0aW9uPyAgDQojUGVyIGNhcGl0YSA9IFVuaXQgLyBOdW1iZXIgb2YgcGVvcGxlIGluIGEgcG9wdWxhdGlvbg0KbmVpZ2hib3VyaG9vZF9yYXRpbmdfam9pbmVkICU+JSANCiAgZmlsdGVyKHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlID09ICJNb3JlIHRoYW4gMTAgbWludXRlcyIpICU+JSANCiAgY291bnQoY2FfbmFtZSkgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpDQpgYGANCg0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBjb3VudChjYV9uYW1lKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkYXRlX2NvZGUgPT0gIjIwMTkiLA0KICAgIHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlID09ICJMZXNzIHRoYW4gMTAgbWludXRlcyIpICU+JSANCiAgY291bnQoY2FfbmFtZSkgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpDQpgYGANCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmdfam9pbmVkICU+JSANCiAgZmlsdGVyKGRhdGVfY29kZSA9PSAiMjAxOSIsDQogICAgd2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgPT0gIk1vcmUgdGhhbiAxMCBtaW51dGVzIikgJT4lIA0KICBjb3VudChjYV9uYW1lKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkYXRlX2NvZGUgPT0gIjIwMTkiKSAlPiUgDQogIGNvdW50KGNhX25hbWUpICU+JSANCiAgYXJyYW5nZShkZXNjKG4pKQ0KYGBgDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkYXRlX2NvZGUgPT0gIjIwMTgiKSAlPiUgDQogIGNvdW50KGNhX25hbWUpICU+JSANCiAgYXJyYW5nZShkZXNjKG4pKQ0KYGBgDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGNvdW50KGRhdGVfY29kZSkNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkYXRlX2NvZGUgPT0gIjIwMTciKSAlPiUgDQogIGNvdW50KGNhX25hbWUpICU+JSANCiAgYXJyYW5nZShkZXNjKG4pKQ0KYGBgDQoNCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmdfam9pbmVkICU+JSANCiAgZmlsdGVyKGRhdGVfY29kZSA9PSAiMjAxNiIpICU+JSANCiAgY291bnQoY2FfbmFtZSkgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBjb3VudCh1cmJhbl9ydXJhbF9jbGFzc2lmaWNhdGlvbikNCmBgYA0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGNvdW50KHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uKQ0KYGBgDQpgYGB7cn0NCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBjb3VudChkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpDQpgYGANCg0KYGBge3J9DQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgY291bnQoZ2VuZGVyKQ0KYGBgDQoNCiMjQXJlIHRoZXJlIGNlcnRhaW4gZ3JvdXBzIHRoYXQgaGF2ZS8gbGFjayBsb2NhbCBhY2Nlc3MgdG8gZ3JlZW4gc3BhY2U/DQoNCg0KYGBge3J9DQpncmVlbl9zcGFjZXNfam9pbmVkDQpgYGANCg0KYGBge3J9DQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgY291bnQoZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKQ0KYGBgDQoNCmBgYHtyfQ0KI21hbGUvZmVtYWxlIGFjY2Vzcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UgPT0gIkEgNSBtaW51dGUgd2FsayBvciBsZXNzIikgJT4lIA0KICBjb3VudChnZW5kZXIpDQpgYGANCmBgYHtyfQ0KI21hbGUvZmVtYWxlIGFjY2Vzcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UgPT0gIkFuIDExIG1pbnV0ZSB3YWxrIG9yIG1vcmUiKSAlPiUgDQogIGNvdW50KGdlbmRlcikNCmBgYA0KYGBge3J9DQojbWFsZS9mZW1hbGUgYWNjZXNzDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgZmlsdGVyKGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSA9PSAiV2l0aGluIGEgNi0xMCBtaW51dGUgd2FsayIpICU+JSANCiAgY291bnQoZ2VuZGVyKQ0KYGBgDQoNCmBgYHtyfQ0KI2FnZSBhY2Nlc3MNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBjb3VudChhZ2UpDQpgYGANCg0KYGBge3J9DQojYWdlIGFjY2Vzcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogIGZpbHRlcihkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UgPT0gIkEgNSBtaW51dGUgd2FsayBvciBsZXNzIiwNCiAgICAgICAgIGRhdGVfY29kZSA9PSAiMjAxOCIpICU+JSANCiAgY291bnQoYWdlKQ0KYGBgDQoNCmBgYHtyfQ0KI2FnZSBhY2Nlc3MNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBmaWx0ZXIoZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlID09ICJBbiAxMSBtaW51dGUgd2FsayBvciBtb3JlIikgJT4lIA0KICBjb3VudChhZ2UpDQpgYGANCmBgYHtyfQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZA0KYGBgDQoNCmBgYHtyfQ0KI3NpbWRfcXVpbnRpbGVzDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgZmlsdGVyKGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSA9PSAiQSA1IG1pbnV0ZSB3YWxrIG9yIGxlc3MiLCANCiAgICAgICAgIGRhdGVfY29kZSA9PSAiMjAxMyIpICU+JSANCiAgY291bnQoc2ltZF9xdWludGlsZXMpDQpgYGANCmBgYHtyfQ0KI3NpbWRfcXVpbnRpbGVzDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgZmlsdGVyKGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSA9PSAiQW4gMTEgbWludXRlIHdhbGsgb3IgbW9yZSIpICU+JSANCiAgY291bnQoc2ltZF9xdWludGlsZXMpDQpgYGANCg0KYGBge3J9DQpncmVlbl9zcGFjZXNfam9pbmVkDQpgYGANCmBgYHtyfQ0KI3NpbWRfcXVpbnRpbGVzDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgZmlsdGVyKGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSA9PSAiQSA1IG1pbnV0ZSB3YWxrIG9yIGxlc3MiLCANCiAgICAgICAgIGRhdGVfY29kZSA9PSAiMjAxOSIpICU+JSANCiAgY291bnQoc2ltZF9xdWludGlsZXMpDQpgYGANCg0KDQpgYGB7cn0NCiNzaW1kX3F1aW50aWxlcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogIGdyb3VwX2J5KGRhdGVfY29kZSkgJT4lIA0KICBmaWx0ZXIoZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlID09ICJBIDUgbWludXRlIHdhbGsgb3IgbGVzcyIpDQoNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KZ2dwbG90KGFlcyh4ID0gc2ltZF9xdWludGlsZXMsIGNvbG91ciA9IHNpbWRfcXVpbnRpbGVzKSkrDQogIGdlb21fYmFyKCkNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBtdXRhdGUoYWdlID0gZmFjdG9yKGFnZSwgbGV2ZWxzID0gYygiMTYtMzQgeWVhcnMiLCAiMzUtNjQgeWVhcnMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNjUgeWVhcnMgYW5kIG92ZXIiLCAiQWxsIikpLA0KICAgICAgICAgc2ltZF9xdWludGlsZXMgPSBmYWN0b3Ioc2ltZF9xdWludGlsZXMsIGxldmVscyA9IGMoIjIwJSBtb3N0IGRlcHJpdmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI4MCUgbGVhc3QgZGVwcml2ZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbCIpKSwNCiAgICAgICAgIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSA9IGZhY3RvcigNCiAgICAgICAgICAgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlLCBsZXZlbHMgPSBjKA0KICAgICAgICAgICAgICJBIDUgbWludXRlIHdhbGsgb3IgbGVzcyIsDQogICAgICAgICAgICAgIldpdGhpbiBhIDYtMTAgbWludXRlIHdhbGsiLA0KICAgICAgICAgICAgICJBbiAxMSBtaW51dGUgd2FsayBvciBtb3JlIiwNCiAgICAgICAgICAgICAiRG9uJ3QgS25vdyINCiAgICAgICAgICAgKQ0KICAgICAgICAgKSkgDQpgYGANCg0KDQpgYGB7cn0NCiNwbG90dGluZyBzaW1kX3F1aW50aWxlcyBmb3IgZXZlcnkgeWVhciB0byBzZWUgaWYgdGhlcmUncmUgc2lnbmlmaWNhbnQgDQojZGlmZmVyZW5jZXMgZm9yIGVhY2ggeWVhcg0KI0ZpbHRlcmluZyBvdXQgU2ltZF9xdWludGlsZXMgPT0gIkFsbCINCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBmaWx0ZXIoc2ltZF9xdWludGlsZXMgIT0gIkFsbCIpICU+JSANCmdncGxvdChhZXMoeCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSwgZmlsbCA9IHNpbWRfcXVpbnRpbGVzKSkrDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikrDQogIGZhY2V0X3dyYXAofmRhdGVfY29kZSkNCmBgYA0KDQpgYGB7cn0NCiNwbG90dGluZyBleGNsdWRpbmcgb3V0bGllcnMNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBmaWx0ZXIobWVhc3VyZW1lbnQgPT0gIlBlcmNlbnQiKSAlPiUgDQpnZ3Bsb3QoYWVzKHggPSBzaW1kX3F1aW50aWxlcywgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBmYWNldF93cmFwKH5kYXRlX2NvZGUpDQpgYGANCg0KDQpgYGB7cn0NCiNwbG90dGluZyB3YWxraW5nIGRpc3RuYWNlIGZvciB0b3RhbCB5ZWFycw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQpnZ3Bsb3QoYWVzKHggPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UsIGZpbGwgPSBzaW1kX3F1aW50aWxlcykpKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KYGBge3J9DQojYWdlIGFuZCBkaXN0YW5jZSB0byBncmVlbiBzcGFjZXMgDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgICBncm91cF9ieShhZ2UsIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBhZ2UsIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCmdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICAgICNmaWx0ZXIobWVhc3VyZW1lbnQgPT0gIlBlcmNlbnQiKSAlPiUgDQogICAgZ3JvdXBfYnkoY2FfbmFtZSwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGNhX25hbWUsIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsgDQogICAgICAgICAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogIGZhY2V0X3dyYXAofmNhX25hbWUpDQpgYGANCg0KYGBge3J9DQojc2ltZCBxdWluaXRsZXMgYW5kIGRpc3RhbmNlIHRvIGdyZWVuIHNwYWNlcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUNCiAgZmlsdGVyKHNpbWRfcXVpbnRpbGVzICE9ICJBbGwiKSAlPiUgDQogICAgZ3JvdXBfYnkoc2ltZF9xdWludGlsZXMsIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzaW1kX3F1aW50aWxlcywgeSA9IG1lYW5fcGVyY2VudGFnZSwgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KYGBge3J9DQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgICAjZmlsdGVyKG1lYXN1cmVtZW50ID09ICJQZXJjZW50IikgJT4lIA0KICAgIGdyb3VwX2J5KCwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHNpbWRfcXVpbnRpbGVzLCB5ID0gbWVhbl9wZXJjZW50YWdlLCBmaWxsID0gZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSkrDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KDQoNCg0KYGBge3J9DQojc3Vic2V0dGluZyB0aGUgQWxsDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgICAjZmlsdGVyKG1lYXN1cmVtZW50ID09ICJQZXJjZW50IikgJT4lIA0KICAgIGdyb3VwX2J5KHNpbWRfcXVpbnRpbGVzLCBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpICU+JSANCiAgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlID0gbWVhbih2YWx1ZSkpICU+JSANCiAgZ2dwbG90KHN1YnNldChncmVlbl9zcGFjZXNfam9pbmVkLCBzaW1kX3F1aW50aWxlcyAlaW4lIGMoIkFsbCIpKSkrDQogIGdlb21fY29sKGFlcyhzaW1kX3F1aW50aWxlcywgbWVhbl9wZXJjZW50YWdlLCBmaWxsID0gZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSkNCmBgYA0KDQpgYGB7cn0NCiNnZW5kZXIgYW5kIGRpc3RhbmNlIHRvIGdyZWVuIHNwYWNlcyANCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICAgIGdyb3VwX2J5KGdlbmRlciwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGdlbmRlciwgeSA9IG1lYW5fcGVyY2VudGFnZSwgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KYGBge3J9DQojdXJiYW4vIHJ1cmFsIGFyZWFzIGFuZCBhY2Nlc3MgdG8gZ3JlZW4gc3BhY2VzDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgICBncm91cF9ieSh1cmJhbl9ydXJhbF9jbGFzc2lmaWNhdGlvbiwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uLCB5ID0gbWVhbl9wZXJjZW50YWdlLCBmaWxsID0gZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSkrDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KDQpgYGB7cn0NCiN0eXBlIG9mIHRlbnVyZSBhbmQgZGlzdGFuY2UgdG8gbmVhcmVzdCBncmVlbiBzcGFjZQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogZmlsdGVyKHR5cGVfb2ZfdGVudXJlICE9ICJBbGwiKSAlPiUgDQogICAgIGdyb3VwX2J5KHR5cGVfb2ZfdGVudXJlLCBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpICU+JSANCiAgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlID0gbWVhbih2YWx1ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gdHlwZV9vZl90ZW51cmUsIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KI2hvdXNlaG9sZCB0eXBlIGFuZCBkaXN0YW5jZSB0byBncmVlbiBzcGFjZXMNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBmaWx0ZXIoaG91c2Vob2xkX3R5cGUgIT0gIkFsbCIpICU+JSANCiAgICBncm91cF9ieShob3VzZWhvbGRfdHlwZSwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGhvdXNlaG9sZF90eXBlLCB5ID0gbWVhbl9wZXJjZW50YWdlLCBmaWxsID0gZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSkrDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KDQpgYGB7cn0NCiNldGhuaWNpdHkNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICAgIGdyb3VwX2J5KGV0aG5pY2l0eSwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGV0aG5pY2l0eSwgeSA9IG1lYW5fcGVyY2VudGFnZSwgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KYGBge3J9DQojZXRobmljaXR5IGFuZCB0cnlpbmcgdG8gc3Vic2V0ICJBbGwiDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiAgICBncm91cF9ieShldGhuaWNpdHksIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3Qoc3Vic2V0KGV0aG5pY2l0eSAlaW4lICJBbGwiKSwgYWVzKHggPSBldGhuaWNpdHksIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KICAgZ2dwbG90KHN1YnNldChncmVlbl9zcGFjZXNfam9pbmVkLA0KICAgICAgICAgICAgICAgICBldGhuaWNpdHkgJWluJSAiQWxsIiksIGFlcyh4ID0gZXRobmljaXR5LCB5ID0gdmFsdWUsIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KI2V0aG5pY2l0eQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogICAgZ3JvdXBfYnkoZXRobmljaXR5LCBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpICU+JSANCiAgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlID0gbWVhbih2YWx1ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZXRobmljaXR5KC1jKCJBbGwiKSksIA0KICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KI2V0aG5pY2l0eQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogICAgZ3JvdXBfYnkoZXRobmljaXR5KC1jKCJBbGwiKSksIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBldGhuaWNpdHksIA0KICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KI2V0aG5pY2l0eQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogIGZpbHRlcihldGhuaWNpdHkgIT0gIkFsbCIpICU+JSANCiAgICBncm91cF9ieShldGhuaWNpdHksIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBldGhuaWNpdHksIA0KICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQoNCmBgYHtyfQ0KI2V0aG5pY2l0eQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogZmlsdGVyKGV0aG5pY2l0eSAhPSAiQWxsIikgJT4lIA0KICAgIGdyb3VwX2J5KGV0aG5pY2l0eSwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGV0aG5pY2l0eSwgDQogICAgICAgICAgICAgeSA9IG1lYW5fcGVyY2VudGFnZSwgDQogICAgICAgICAgICAgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlc19qb2luZWQNCmBgYA0KDQpgYGB7cn0NCiNnZW5kZXIgYW5kIGRpc3RhbmNlIHRvIGdyZWVuIHNwYWNlcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogZmlsdGVyKGdlbmRlciAhPSAiQWxsIikgJT4lIA0KICAgIGdyb3VwX2J5KGdlbmRlciwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGdlbmRlciwgDQogICAgICAgICAgICAgeSA9IG1lYW5fcGVyY2VudGFnZSwgDQogICAgICAgICAgICAgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KYGBge3J9DQojZ2VuZGVyIGFuZCBkaXN0YW5jZSB0byBncmVlbiBzcGFjZXMNCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KIGZpbHRlcih1cmJhbl9ydXJhbF9jbGFzc2lmaWNhdGlvbiAhPSAiQWxsIikgJT4lIA0KICAgIGdyb3VwX2J5KHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uLCBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpICU+JSANCiAgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlID0gbWVhbih2YWx1ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gdXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24sIA0KICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgIGZpbGwgPSBkaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuX29yX2JsdWVfc3BhY2UpKSsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKQ0KYGBgDQojd29ya2luZyBvbiBuZWlnaGJvdXJob29kIHJhdGluZw0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQNCmBgYA0KDQpgYGB7cn0NCmNvbW11bml0eV9iZWxvbmdpbmdfam9pbmVkDQpgYGANCg0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBjb3VudChuZWlnaGJvdXJob29kX3JhdGluZykNCmBgYA0KDQoNCg0KI2ludGVyZXN0aW5nIGRhdGEsIG1heWJlIEknbGwgbmVlZCB0byBiaW4gdGhlIGRhdGEgaW50byBnb29kIGFuZCBwb29yLCB0aGUgZGlmZmVyZW5jZSBpcyBtYXliZSBtb3JlIGV2aWRlbnQgb3IgcGVyaGFwcyBJIGNhbiBwbG90IHRoZSBkaWZmZXJlbmNlcyBpbiB0d28gZGlmZmVyZW50IHBsb3RzLg0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nX2pvaW5lZCAlPiUgDQogIGZpbHRlcih3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSAhPSAiQWxsIikgJT4lIA0KICAgIGdyb3VwX2J5KG5laWdoYm91cmhvb2RfcmF0aW5nLCB3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBuZWlnaGJvdXJob29kX3JhdGluZywgDQogICAgICAgICAgICAgeSA9IG1lYW5fcGVyY2VudGFnZSwgDQogICAgICAgICAgICAgZmlsbCA9IHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlKSkrDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgIT0gIkFsbCIsIA0KICAgICAgICAgbmVpZ2hib3VyaG9vZF9yYXRpbmcgPT0gIlZlcnkgZ29vZCIpICU+JSANCiAgICBncm91cF9ieShuZWlnaGJvdXJob29kX3JhdGluZywgd2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UpICU+JSANCiAgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlID0gbWVhbih2YWx1ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbmVpZ2hib3VyaG9vZF9yYXRpbmcsIA0KICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgIGZpbGwgPSB3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KYGBge3J9DQpuZWlnaGJvdXJob29kX3JhdGluZ19qb2luZWQgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgIT0gIkFsbCIsIA0KICAgICAgICAgbmVpZ2hib3VyaG9vZF9yYXRpbmcgPT0gIlZlcnkgcG9vciIpICU+JSANCiAgICBncm91cF9ieShuZWlnaGJvdXJob29kX3JhdGluZywgd2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UpICU+JSANCiAgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50YWdlID0gbWVhbih2YWx1ZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbmVpZ2hib3VyaG9vZF9yYXRpbmcsIA0KICAgICAgICAgICAgIHkgPSBtZWFuX3BlcmNlbnRhZ2UsIA0KICAgICAgICAgICAgIGZpbGwgPSB3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCg0KI2Jpbm5pbmcgaW50byBnb29kIGFuZCB2ZXJ5IGdvb2QgYW5kIHBvb3IgYW5kIHZlcnkgcG9vciANCg0KDQpgYGB7cn0NCiN1cmJhbi8gcnVyYWwgYXJlYXMgYW5kIGRpc3RhbmNlIHRvIGdyZWVuIHNwYWNlcw0KZ3JlZW5fc3BhY2VzX2pvaW5lZCAlPiUgDQogZmlsdGVyKHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uICE9ICJBbGwiKSAlPiUgDQogICAgZ3JvdXBfYnkodXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24sIGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkgJT4lIA0KICAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnRhZ2UgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB1cmJhbl9ydXJhbF9jbGFzc2lmaWNhdGlvbiwgDQogICAgICAgICAgICAgeSA9IG1lYW5fcGVyY2VudGFnZSwgDQogICAgICAgICAgICAgZmlsbCA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQpgYGANCmBgYHtyfQ0KI3VyYmFuLyBydXJhbCBhcmVhcyBhbmQgZGlzdGFuY2UgdG8gZ3JlZW4gc3BhY2VzDQpncmVlbl9zcGFjZXNfam9pbmVkICU+JSANCiBmaWx0ZXIodXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24gIT0gIkFsbCIsIA0KICAgICAgICBtZWFzdXJlbWVudCA9PSAiUGVyY2VudCIpICU+JSANCiAgICBncm91cF9ieSh1cmJhbl9ydXJhbF9jbGFzc2lmaWNhdGlvbiwgZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4odmFsdWUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uLCANCiAgICAgICAgICAgICB5ID0gbWVhbl9wZXJjZW50YWdlLCANCiAgICAgICAgICAgICBmaWxsID0gZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKSkrDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikNCmBgYA0KDQoNCg0KI2xldCdzIGRvIGh5cG90aGVzaXMgdGVzdGluZyBvbiB1cmJhbiBhbmQgcnVyYWwgDQoNCmBgYHtyfQ0KZ3JlZW5fc3BhY2VzX2pvaW5lZA0KYGBgDQpgYGB7cn0NCmdyZWVuX3NwYWNlc19qb2luZWQgJT4lIA0KICBjb3VudChtZWFzdXJlbWVudCkNCmBgYA0KI2FyZSB0aGVyZSBkaWZmZXJlbmNlcyBpbiBncmVlbiBzcGFjZXMgYWNjZXNzIGJldHdlZW4gcnVyYWwgb3IgdXJiYW4gDQoNCmBgYHtyfQ0KDQpgYGANCg0KDQoNCg0K